﻿using Cms.Application.Admin.Presenters;
using Cms.Application.Admin.Views;
using Cms.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Cms.Tests.Unit.Application.Admin.Presenters
{
    [TestClass]
    public class EditUserPresenterTests : BasePresenterTests
    {
        private Mock<IEditUserView> _viewMock;
        private Administrator _admin;
        private AdministratorGroup _adminGroup;
        private AdministratorGroup _regularGroup;
        private User _user;

        private void Prepare()
        {
            InitRepositoryFactoryMock();
            _viewMock = new Mock<IEditUserView>();
            _viewMock.SetupAllProperties();
            _viewMock.SetupGet(m => m.AdministratorID).Returns(1);
            _viewMock.Setup(m => m.Localization).Returns("en-US");
            _viewMock.Setup(m => m.ContextTranslationFile).Returns("Admin/Translations/EditUser.xml");
            _admin = new Administrator() { ID = 1 };
            _adminGroup = new AdministratorGroup() { ID = 1 };
            _regularGroup = new AdministratorGroup();
            AdministratorRepositoryMock.Setup(m => m.GetAdministrator(1)).Returns(_admin);
            _user = new User() { ID = 1 };
            UserRepositoryMock.Setup(m => m.GetUser(1)).Returns(_user);
        }

        [TestMethod]
        public void Constructor_AdminHasAccess_Allowed()
        {
            Prepare();
            _viewMock.SetupGet(m => m.EditedUserID).Returns(1);
            _admin.Group = _adminGroup;
            EditUserPresenter presenter = new EditUserPresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.Verify(m => m.RedirectToPermissionDeniedPage(), Times.Never());
        }

        [TestMethod]
        public void Constructor_AdminHasNoAccess_Denied()
        {
            Prepare();
            _viewMock.SetupGet(m => m.EditedUserID).Returns(1);
            _admin.Group = _regularGroup;
            EditUserPresenter presenter = new EditUserPresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.Verify(m => m.RedirectToPermissionDeniedPage(), Times.Exactly(1));
        }

        [TestMethod]
        public void Constructor_InvalidEditedUserID_RedirectToBadRequestParameter()
        {
            Prepare();
            _viewMock.SetupGet(m => m.EditedUserID).Returns(0);
            EditUserPresenter presenter = new EditUserPresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.Verify(m => m.RedirectToBadRequestParameterPage(), Times.Exactly(1));
        }

        [TestMethod]
        public void Initialize_NewUser_ViewIsLeftBlank()
        {
            Prepare();
            _viewMock.SetupGet(m => m.EditedUserID).Returns(-1);
            EditUserPresenter presenter = new EditUserPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Initialize();
            _viewMock.Verify(m => m.Username, Times.Never());
        }

        [TestMethod]
        public void Initialize_EditUser_ViewIsUpdated()
        {
            Prepare();
            _viewMock.SetupGet(m => m.EditedUserID).Returns(1);
            _user.Username = "mistaholmes";
            _user.Password = "xxx";
            _user.Firstname = "Fredrik";
            _user.Lastname = "Holm";
            _user.Phone = "070343434";
            _user.Email = "fredrik.holm@infolyzer.se";
            EditUserPresenter presenter = new EditUserPresenter(_viewMock.Object, FactoryMock.Object);
            presenter.Initialize();
            Assert.AreEqual(_user.Username, _viewMock.Object.Username);
            Assert.AreEqual(_user.Password, _viewMock.Object.Password);
            Assert.AreEqual(_user.Firstname, _viewMock.Object.Firstname);
            Assert.AreEqual(_user.Lastname, _viewMock.Object.Lastname);
            Assert.AreEqual(_user.Phone, _viewMock.Object.Phone);
            Assert.AreEqual(_user.Email, _viewMock.Object.Email);
        }

        [TestMethod]
        public void Save_NewUser_UserIsSaved()
        {
            Prepare();
            _viewMock.SetupGet(m => m.EditedUserID).Returns(-1);
            EditUserPresenter presenter = new EditUserPresenter(_viewMock.Object, FactoryMock.Object);
            _viewMock.SetupGet(m => m.Username).Returns("mistaholmes");
            _viewMock.SetupGet(m => m.Password).Returns("xxx");
            _viewMock.SetupGet(m => m.Firstname).Returns("Fredrik");
            _viewMock.SetupGet(m => m.Lastname).Returns("Holm");
            _viewMock.SetupGet(m => m.Phone).Returns("070343434");
            _viewMock.SetupGet(m => m.Email).Returns("fredrik.holm@infolyzer.se");
            presenter.Save();
            UserRepositoryMock.Verify(m => m.SaveUser(It.Is<User>(p =>
                p.Username == "mistaholmes" &&
                p.Password == "xxx" &&
                p.Firstname == "Fredrik" &&
                p.Lastname == "Holm" &&
                p.Phone == "070343434" &&
                p.Email == "fredrik.holm@infolyzer.se")), Times.Exactly(1));
        }
    }
}
